package com.ymx.darling.generater.def;

import com.ymx.darling.bean.entity.BeanInfo;
import com.ymx.darling.bean.entity.BeanInfoRepository;
import com.ymx.darling.bean.entity.DefaultBeanInfoRepository;
import com.ymx.darling.util.ResourceUtil;
import com.ymx.darling.util.StringUtil;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 实体Def配置
 * @author 爱Java的小于
 */
public class EntityDefConfig {
    private final String projectRoot;
    private final String entityPackage;
    private final NamingStyle namingStyle;

    public EntityDefConfig(String projectRoot, String entityPackage, NamingStyle namingStyle) {
        this.projectRoot = System.getProperty("user.dir") +"/"+ projectRoot;
        this.entityPackage = entityPackage;
        this.namingStyle = namingStyle;
    }

    public void start() {
        // 判断没有配置实体包时直接返回
        if (StringUtil.isNull(this.entityPackage)) {
            return;
        }

        BeanInfoRepository beanInfoRepository = new DefaultBeanInfoRepository();
        List<Class<?>> classes = ResourceUtil.getClassListByPackage(this.entityPackage);
        System.out.println(">>>>>>>>>开始生成实体的Def...");
        for (Class<?> entity : classes) {
            try {
                if (beanInfoRepository.isScannerForEntity(entity)) {
                    beanInfoRepository.register(entity);
                    BeanInfo beanInfo = beanInfoRepository.getBeanInfo(entity);
                    if (beanInfo.isTableEntity()) { // 只有表实体类型才生成
                        this.createEntityDef(beanInfo);
                    }
                }
            } catch (Exception exception) {
                System.err.printf("生成实体%s的Def时出错.原因:%s:%s%n", entity.getName(), exception.getClass().getName(), exception.getMessage());
            }
        }
    }


    /**
     * 创建实体Def
     * @param beanInfo BeanInfo
     */
    private void createEntityDef(BeanInfo beanInfo) {
        // 获取 entity 类名
        String entityClassName = beanInfo.getModule().getSimpleName()+"Def";
        String tableName = NamingConverter.convertNamingStyle(beanInfo.getTableName(), NamingStyle.CAMEL_CASE);

        String packageName = this.entityPackage + "." + "def";
        Map<String, String> defaultColumnMap = new HashMap<>();
        beanInfo.getSimpleColumnMap().forEach((columnName, columnInfo) ->
                defaultColumnMap.put(columnInfo.getProperty(), columnName)
        );
        // 构建类内容
        String content = ContentBuilder.buildTableDef(packageName, entityClassName, tableName, defaultColumnMap, namingStyle);
        // 开始生成
        String packageAbsolutePath = this.projectRoot + "/def";
        buildFile(packageAbsolutePath, entityClassName, content);
    }


    /**
     * 生成类文件
     * @param aboutPath 绝对路径（不带文件名）
     * @param className 类名（不需要.java后缀）
     * @param context 类文件内容
     */
    public static void buildFile(String aboutPath, String className, String context) {
        // 确保路径以分隔符结尾
        if (!aboutPath.endsWith(File.separator)) {
            aboutPath += File.separator;
        }

        // 创建目录结构
        File directory = new File(aboutPath);
        if (!directory.exists()) {
            boolean dirsCreated = directory.mkdirs();
            if (!dirsCreated) {
                System.err.println("无法创建目录: " + aboutPath);
            }
        }

        // 构建完整文件路径
        String filePath = aboutPath + className + ".java";

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            writer.write(context);
            System.out.println(filePath);
        } catch (IOException e) {
            System.err.printf(String.format("生成类文件'%s'时出错:%s:%s ", filePath, e.getClass().getName(), e.getMessage()));
        }
    }
}
